from flask import request, jsonify, g
from flask_jwt_extended import jwt_required
import datetime
from bson import ObjectId
import logging

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required, hash_password, check_password
from app.schemas.user import UserSchema, UserUpdateSchema, UserQuerySchema, PasswordResetSchema
from app.utils.common import normalize_data, paginate, generate_id

# 配置日志
logger = logging.getLogger(__name__)

@api_bp.route('/users', methods=['GET'])
@jwt_required()
@permission_required('user:read')
def get_users():
    """获取用户列表"""
    # 获取查询参数
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'createdAt')
    order = request.args.get('order', 'desc')
    
    # 构建查询条件
    query = {}
    
    # 按用户名筛选
    username = request.args.get('username')
    if username:
        query['username'] = {'$regex': username, '$options': 'i'}
    
    # 按角色筛选
    role = request.args.get('role')
    if role and role != 'all':
        query['role'] = role
    
    # 按部门筛选
    department_id = request.args.get('departmentId')
    if department_id:
        query['departmentId'] = department_id
    
    # 按状态筛选
    status = request.args.get('status')
    if status and status != 'all':
        query['status'] = status
    
    # 确定排序
    sort_direction = -1 if order.lower() == 'desc' else 1
    
    # 获取数据
    users_cursor = mongo.db.users.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(users_cursor, page, limit)
    
    # 标准化数据
    users = []
    for user in paginated_data['items']:
        # 移除敏感信息
        user.pop('password', None)
        
        # 获取部门信息
        department_name = ''
        if 'departmentId' in user and user['departmentId']:
            dept_id = user['departmentId']
            if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
                dept_id = ObjectId(dept_id)
            department = mongo.db.departments.find_one({'_id': dept_id})
            if department:
                department_name = department.get('name', '')
        
        # 标准化用户数据
        normalized_user = normalize_data(user)
        normalized_user['departmentName'] = department_name
        users.append(normalized_user)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'users': users
        }
    }), 200

@api_bp.route('/users/<id>', methods=['GET'])
@jwt_required()
@permission_required('user:read')
def get_user(id):
    """获取用户详情"""
    # 查询用户
    user = None
    if ObjectId.is_valid(id):
        user = mongo.db.users.find_one({'_id': ObjectId(id)})
    
    if not user:
        user = mongo.db.users.find_one({'username': id})
    
    if not user:
        return jsonify({
            'success': False,
            'message': '用户不存在'
        }), 404
    
    # 移除敏感信息
    user.pop('password', None)
    
    # 获取部门信息
    department_info = None
    if 'departmentId' in user and user['departmentId']:
        dept_id = user['departmentId']
        if isinstance(dept_id, str) and ObjectId.is_valid(dept_id):
            dept_id = ObjectId(dept_id)
        department = mongo.db.departments.find_one({'_id': dept_id})
        if department:
            department_info = {
                'id': str(department['_id']),
                'name': department.get('name', ''),
                'description': department.get('description', '')
            }
    
    # 获取角色信息
    role_info = None
    if 'role' in user:
        role = user['role']
        role_doc = mongo.db.roles.find_one({'name': role})
        if role_doc:
            role_info = {
                'name': role_doc['name'],
                'displayName': role_doc.get('displayName', role),
                'permissions': role_doc.get('permissions', [])
            }
    
    # 标准化数据
    normalized_user = normalize_data(user)
    
    return jsonify({
        'success': True,
        'data': {
            'user': normalized_user,
            'departmentInfo': department_info,
            'roleInfo': role_info
        }
    }), 200

@api_bp.route('/users', methods=['POST'])
@jwt_required()
@permission_required('user:create')
def create_user():
    """创建用户"""
    # 验证请求数据
    schema = UserSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 检查用户名是否已存在
    if mongo.db.users.find_one({'username': data['username']}):
        return jsonify({
            'success': False,
            'message': '用户名已存在'
        }), 400
    
    # 检查邮箱是否已存在
    if mongo.db.users.find_one({'email': data['email']}):
        return jsonify({
            'success': False,
            'message': '邮箱已存在'
        }), 400
    
    # 如果有staffId，检查是否已存在
    if 'staffId' in data and data['staffId']:
        if mongo.db.users.find_one({'staffId': data['staffId']}):
            return jsonify({
                'success': False,
                'message': '工号已存在'
            }), 400
    else:
        # 如果没有提供staffId，生成一个
        role_prefix = {
            'admin': 'A',
            'doctor': 'D',
            'nurse': 'N',
            'pharmacist': 'P',
            'patient': 'PT'
        }.get(data['role'], 'U')
        data['staffId'] = generate_id(role_prefix)
    
    # 对密码进行哈希处理
    data['password'] = hash_password(data['password'])
    
    # 添加创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    data['lastLogin'] = None
    
    # 保存到数据库
    result = mongo.db.users.insert_one(data)
    
    # 创建成功后，如果是医生角色，还需要在doctors集合中创建一条记录
    if data['role'] == 'doctor':
        doctor_data = {
            'userId': result.inserted_id,
            'staffId': data['staffId'],
            'name': data['name'],
            'gender': data.get('personalInfo', {}).get('gender', '未知'),
            'title': data.get('personalInfo', {}).get('title', ''),
            'departmentId': ObjectId(data['departmentId']) if 'departmentId' in data and data['departmentId'] else None,
            'specialties': data.get('personalInfo', {}).get('specialties', []),
            'contactInfo': {
                'phone': data.get('phone', ''),
                'email': data.get('email', ''),
                'office': ''
            },
            'status': '在职',
            'createdAt': now,
            'updatedAt': now
        }
        mongo.db.doctors.insert_one(doctor_data)
    
    return jsonify({
        'success': True,
        'message': '用户创建成功',
        'data': {
            'id': str(result.inserted_id),
            'username': data['username'],
            'name': data['name'],
            'role': data['role'],
            'staffId': data['staffId'],
            'createdAt': now.isoformat()
        }
    }), 201

@api_bp.route('/users/<id>', methods=['PUT'])
@jwt_required()
@permission_required('user:update')
def update_user(id):
    """更新用户信息"""
    # 查询用户
    user = None
    if ObjectId.is_valid(id):
        user = mongo.db.users.find_one({'_id': ObjectId(id)})
    
    if not user:
        return jsonify({
            'success': False,
            'message': '用户不存在'
        }), 404
    
    # 验证请求数据
    schema = UserUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 检查用户名是否已存在（如果有更改）
    if 'username' in data and data['username'] != user['username']:
        if mongo.db.users.find_one({'username': data['username']}):
            return jsonify({
                'success': False,
                'message': '用户名已存在'
            }), 400
    
    # 检查邮箱是否已存在（如果有更改）
    if 'email' in data and data['email'] != user['email']:
        if mongo.db.users.find_one({'email': data['email']}):
            return jsonify({
                'success': False,
                'message': '邮箱已存在'
            }), 400
    
    # 如果修改了密码，对新密码进行哈希处理
    if 'password' in data and data['password']:
        data['password'] = hash_password(data['password'])
    else:
        # 不更新密码
        data.pop('password', None)
    
    # 更新时间
    data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    mongo.db.users.update_one({'_id': ObjectId(id)}, {'$set': data})
    
    # 如果更新的是医生用户，同时更新doctors集合
    if user['role'] == 'doctor':
        doctor_update = {}
        
        if 'name' in data:
            doctor_update['name'] = data['name']
        
        if 'personalInfo' in data:
            if 'gender' in data['personalInfo']:
                doctor_update['gender'] = data['personalInfo']['gender']
            if 'title' in data['personalInfo']:
                doctor_update['title'] = data['personalInfo']['title']
            if 'specialties' in data['personalInfo']:
                doctor_update['specialties'] = data['personalInfo']['specialties']
        
        if 'departmentId' in data:
            doctor_update['departmentId'] = ObjectId(data['departmentId']) if data['departmentId'] else None
        
        if 'email' in data or 'phone' in data:
            doctor_update['contactInfo'] = {
                'phone': data.get('phone', user.get('phone', '')),
                'email': data.get('email', user.get('email', '')),
                'office': ''
            }
        
        if doctor_update:
            doctor_update['updatedAt'] = data['updatedAt']
            mongo.db.doctors.update_one({'userId': ObjectId(id)}, {'$set': doctor_update})
    
    return jsonify({
        'success': True,
        'message': '用户信息更新成功',
        'data': None
    }), 200

@api_bp.route('/users/<id>', methods=['DELETE'])
@jwt_required()
@permission_required('user:delete')
def delete_user(id):
    """删除用户"""
    # 不允许删除自己
    if str(g.current_user['_id']) == id:
        return jsonify({
            'success': False,
            'message': '不能删除当前登录用户'
        }), 400
    
    # 查询用户
    user = None
    if ObjectId.is_valid(id):
        user = mongo.db.users.find_one({'_id': ObjectId(id)})
    
    if not user:
        return jsonify({
            'success': False,
            'message': '用户不存在'
        }), 404
    
    # 删除数据库中的用户
    mongo.db.users.delete_one({'_id': ObjectId(id)})
    
    # 如果是医生用户，同时删除doctors集合中的记录
    if user['role'] == 'doctor':
        mongo.db.doctors.delete_one({'userId': ObjectId(id)})
    
    return jsonify({
        'success': True,
        'message': '用户删除成功',
        'data': None
    }), 200

@api_bp.route('/users/<id>/reset-password', methods=['POST'])
@jwt_required()
@permission_required('user:update')
def reset_user_password(id):
    """重置用户密码"""
    # 记录当前操作用户
    current_user = g.current_user
    
    # 查询目标用户
    user = None
    if ObjectId.is_valid(id):
        user = mongo.db.users.find_one({'_id': ObjectId(id)})
    
    if not user:
        logger.warning(f"密码重置失败: 用户ID {id} 不存在. 操作者: {current_user.get('username')}")
        return jsonify({
            'success': False,
            'message': '用户不存在'
        }), 404
    
    # 验证请求数据
    schema = PasswordResetSchema()
    errors = schema.validate(request.json)
    if errors:
        logger.warning(f"密码重置数据验证失败: {errors}. 目标用户: {user.get('username')}, 操作者: {current_user.get('username')}")
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    new_password = request.json.get('newPassword')
    
    # 对新密码进行哈希处理
    hashed_password = hash_password(new_password)
    
    # 更新密码和更新时间
    now = datetime.datetime.utcnow()
    result = mongo.db.users.update_one(
        {'_id': ObjectId(id)},
        {'$set': {
            'password': hashed_password,
            'updatedAt': now
        }}
    )
    
    if result.modified_count == 0:
        logger.error(f"密码重置失败: 数据库更新无效. 目标用户: {user.get('username')}, 操作者: {current_user.get('username')}")
        return jsonify({
            'success': False,
            'message': '密码重置失败'
        }), 500
    
    logger.info(f"密码重置成功: 目标用户: {user.get('username')}, 角色: {user.get('role')}, 操作者: {current_user.get('username')}")
    
    return jsonify({
        'success': True,
        'message': '密码重置成功',
        'data': {
            'updatedAt': now.isoformat()
        }
    }), 200 